/*
 *@(#)AdImage.java		20 Sept. 2000
 *
 * Copyright: MetaPlus Inc & Inquiry Management Systems Ltd.  2000
 *
 * This software is the proprietary information of MetaPlus Inc & 
 * Inquiry Management Systems Ltd.  
 * Use is subject to license terms.
 */
package com.ims.iaa.AD;

import com.ims.iaa.IaaDebug; 



import java.io.*; 
import java.awt.*;
import java.awt.image.*;

/** 
 *
 * An <code>AdImage</code> object represents the object wrapper of the image 
 * data that ad spiders had collected. If store in database option is choosed, 
 * the serialized fields in this class will be stored into the tblImage and 
 * tblImageData table. The database access is delegated to the server-side 
 * service <code>SpiderDBConnection</code>. This class can be serialized and 
 * sent to a different JVM. This class implements <code>ImageObserver</code>
 * interface and can be used to determine the image height and width.
 *
 * because this class extend from AdData in version 2.00, so many method has been deleted.
 * some methods have been modify.
 * 
 * @see SpiderDBConnection
 *
 * @author Anthony Zhang
 * @author ShengMeng Bai
 *
 * @version 1.00, 25 Sept. 2000
 * @version 2.00, 28 JUL. 2004
 */
public class AdImage  extends AdData implements Serializable, ImageObserver {


	/**
	  * Flag indicates save image data or not. Default is true. 
	  * Used by ImgLink when connected to the actual image on the web.
	  *
	  * @see ImgLink#connectToResource
	  */
	static public final boolean SAVEIMAGE = true;

	/**
	  * Flag specifies the max image size. Default is 50k. 
	  * Used by ImgLink when connected to the actual image on the web.
	  *
	  * @see ImgLink#connectToResource
	  */
	static public final int MAXIMAGESIZE = IaaDebug.MaxImageSize;
	
	/**
	  * Default toolkit. Either specified by system property 
	  * "awt.toolkit" or default class "sun.awt.motif.MToolkit". This toolkit 
	  * determined the image type supported by this class.
	  *
	  * @see #setImageData
	  */
	static Toolkit toolkit = Toolkit.getDefaultToolkit();

	/**
	  * Image object used to get the height and width information. This field 
	  * can not be send to anthoer JVM. 
	  */
	transient private Image image;

   /**
     * Determines the height of the image. If the height is not yet known, 
	  * this method will wait until notified by the imageUpdate method.
	  * If no image data exist, returns NOTEXIST.
	  *
     * @return The int value of the image height.
     *
	  * @see #setImageData
     * @see #setImageHeight
	  * @see #imageUpdate
     */
   public synchronized void prepareImageHeight()  {
//++**********Add by ShengMeng Bai at 2004-07-29
   	// in old version, the variable imageHeight is a class member field, 
   	// in new version, this variable has been move to super class.
   	int iImageHeight = this.getHeight();
//--**********Add by ShengMeng Bai at 2004-07-29
   	IaaDebug.say("^^^^^^^^^^^^HEIGHT^^^^^^^^^^^^^^^^^ is " +  iImageHeight);

		if (iImageHeight == UNKNOWN ) {
			try  {
				IaaDebug.begin("^^^^^^^^^^^^WAIT FOR HEIGHT^^^^^^^^^^^^^^^^^");
				wait(5000);
	    		IaaDebug.end("^^^^^^^^^^^^WAIT FOR HEIGHT^^^^^^^^^^^^^^^^^");
	    		} catch (InterruptedException e)  {}
		}
		IaaDebug.say("^^^^^^^^^^^^HEIGHT after wait ^^^^^^^^^^^^^^^^^ is " +  iImageHeight);
   }

   /**
     * Determines the width of the image. If the width is not yet known, 
     * this method will wait until notified by imageUpdate method. 
	  * If no image data exist, returns NOTEXIST.
     *
     * @return The int value of the image width.
     *
     * @see #setImageData
     * @see #setImageHeight
	  * @see #imageUpdate
     */
   public synchronized void prepareImageWidth()  {
//++**********Add by ShengMeng Bai at 2004-07-29
   	// in old version, the variable imageWidth is a class member field, 
   	// in new version, this variable has been move to super class.
   	int iImageWidth = this.getWidth();
//--**********Add by ShengMeng Bai at 2004-07-29
		IaaDebug.say("^^^^^^^^^^^^WIDTH^^^^^^^^^^^^^^^^^ is " +  iImageWidth);

   	if (iImageWidth == UNKNOWN ) {
   		try  {
				IaaDebug.begin("^^^^^^^^^^^^WAIT FOR WIDTH^^^^^^^^^^^^^^^^^");
				wait(5000);
				IaaDebug.end("^^^^^^^^^^^^WAIT FOR WIDTH^^^^^^^^^^^^^^^^^");
   		} catch (InterruptedException e)  {}
   	}
		IaaDebug.say("^^^^^^^^^^^^WIDTH after wait^^^^^^^^^^^^^^^^^ is " +  iImageWidth);
   }

   /**
     * Sets the actual image data. 
	  * This method sets the image data, use default toolkit to creat the 
	  * <code>Image</code> object, registers this object as <code>ImageObserver
	  * </code> of the image and call getImageHeight, getImageWidth method.
	  * The image data must be in some image format, such as GIF or JPEG, that is 
	  * supported by the default toolkit (either specified by system property 
	  * "awt.toolkit" or default class "sun.awt.motif.MToolkit").
	  *
	  * This method override the method of super class.
	  *
     * @param imagedata an array of bytes, representing image data in a 
	  *		supported image format
     *
     * @return void
     */
	public void setData(byte[] imagedata)  {
		super.setData(imagedata);
		if (imagedata != null)  {
			image = toolkit.createImage(imagedata);
			//if the height or width is not known yet, the following method
			// return -1 (which is defined as UNKNOWN ) and registered this object as the observer of the image.
//++************modify by ShengMeng Bai at 2004-07-29
			int imageHeight = image.getHeight(this);
			int imageWidth  = image.getWidth(this);
//--************modify by ShengMeng Bai at 2004-07-29




		}
	}
	
	/**
	 * Retrieves the height and width information from the <code>Image</code> 
	 * interface. This method is called when information about the image which 
	 * was previously requested using getHeight and getWidth method of 
	 * asynchronous <code>Image</code> interface becomes available. 
	 * If image height or width information is ready this method set the 
	 * imageHeight and imageWidth field, notify other method and return false to 
	 * indicate no further updates are needed.
	 *
	 *  @return Return false if height and width is available, otherwise true.
	 */
	public synchronized boolean imageUpdate(Image img,
                          int infoflags,
                          int x,
                          int y,
                          int width,
                          int height)  {
		if ((infoflags & ImageObserver.ERROR) == ImageObserver.ERROR )  {
		    IaaDebug.boldSay("ImageObserver.ERROR");    
		    this.setHeight(NOTEXIST);
		    this.setWidth(NOTEXIST);
			notifyAll();
		}
		if( ((infoflags & ImageObserver.WIDTH) == ImageObserver.WIDTH ) &&
		((infoflags & ImageObserver.HEIGHT) == ImageObserver.HEIGHT ) )  {
			this.setHeight(image.getHeight(this));
			this.setWidth(image.getWidth(this));
			notifyAll();
			return false;
		} else  {
			return true;
		}
	}
	

	public static void main(String args[])
	{
		AdImage image = new AdImage();
		String sFile = "C:\\Documents and Settings\\zhufx\\My Documents\\My Pictures\\DB Name.jpg";
		if(args.length > 0){
		    sFile = args[0];
		}
		

		try  {
				FileInputStream in = new FileInputStream(sFile);
				
				BufferedInputStream bs = new BufferedInputStream(in);
			
				byte[] buf = new byte[1024];
				int readNum =0;
		
				ByteArrayOutputStream picOutStream = new ByteArrayOutputStream();
					
				while ( (readNum = bs.read(buf)) != -1)  {
					picOutStream.write(buf,0,readNum);
				}
				bs.close();
			
				image.setData(picOutStream.toByteArray());
				image.prepareImageHeight();
				image.prepareImageWidth();
				picOutStream.close();
				System.out.println("height: " + image.getHeight() );
				System.out.println("width: " + image.getWidth() );
		} catch ( Exception e ) {
		    System.out.println( "!!!!Get image form the connection input stream error " + e );
		}
		System.exit(0);
	}
}